<?php

require_once DEF_ROOT . 'UserDef.php';
require_once DATA_ROOT . 'BaseData.php';
/**
 * This is the model class for table "{{user}}".
 *
 * The followings are the available columns in table '{{user}}':
 * @property string $uid
 * @property string $uname
 * @property string $email
 * @property string $password
 * @property string $city
 * @property integer $sex
 * @property string $photo
 * @property string $notice_config
 * @property string $description
 * @property string $grade
 * @property string $url
 * @property string $create_time
 * @property string $last_login_time
 * @property string $last_modify_time
 * @property string $status
 */
class UserData extends BaseData {

    /**
     * Returns the static model of the specified AR class.
     * @return UserDao the static model class
     */
    public static function model($className=__CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{user}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('email, password, create_time, last_login_time, last_modify_time', 'required'),
            array('sex', 'numerical', 'integerOnly' => true),
            array('notice_config, grade, create_time, last_login_time, last_modify_time, status', 'length', 'max' => 10),
            array('email, description', 'length', 'max' => 50),
            array('password', 'length', 'max' => 32),
            array('photo', 'length', 'max' => 32),
            array('uname, url', 'length', 'max' => 20),
            array('city', 'length', 'max' => 16),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('uid, uname, email, password, city, sex, photo, notice_config, description, grade, url, create_time, last_login_time, last_modify_time, status', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'uid' => 'Uid',
            'uname' => 'Uname',
            'email' => 'Email',
            'password' => 'Password',
            'city' => 'City',
            'sex' => 'Sex',
            'photo' => 'Photo',
            'notice_config' => 'Notice Config',
            'description' => 'Description',
            'grade' => 'Grade',
            'url' => 'Url',
            'create_time' => 'Create Time',
            'last_login_time' => 'Last Login Time',
            'last_modify_time' => 'Last Modify Time',
            'status' => 'Status',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('uid', $this->uid, true);
        $criteria->compare('uname', $this->uname, true);
        $criteria->compare('email', $this->email, true);
        $criteria->compare('password', $this->password, true);
        $criteria->compare('city', $this->city, true);
        $criteria->compare('sex', $this->sex);
        $criteria->compare('photo', $this->photo, true);
        $criteria->compare('notice_config', $this->notice_config, true);
        $criteria->compare('description', $this->description, true);
        $criteria->compare('grade', $this->grade, true);
        $criteria->compare('url', $this->url, true);
        $criteria->compare('create_time', $this->create_time, true);
        $criteria->compare('last_login_time', $this->last_login_time, true);
        $criteria->compare('last_modify_time', $this->last_modify_time, true);
        $criteria->compare('status', $this->status, true);

        return new CActiveDataProvider(get_class($this), array(
            'criteria' => $criteria,
        ));
    }

    public function isIllegalInAdd() {
        return empty($this->uname) ||
        empty($this->email) ||
        empty($this->password);
    }

    public function isIllegalInEdit() {
        return empty($this->uid);
    }
    
    public function getCityId() {
        return $this->city & self::CITY_MASK;
    }

    public function getProvinceId() {
        return ($this->province >> 5) & self::CITY_MASK;
    }

    public function setPassword($pwd, $needMd5 = true) {
        if ($needMd5) {
            $this->password = self::encodePassword($pwd);
        } else {
            $this->password = $pwd;
        }
    }
    
    public function isNoticedWhileFollowed() {
        return $this->notice_config & NoticeConfig::BE_FOLLOWED;
    }

    public function isNoticedWhileFavored() {
        return $this->notice_config & NoticeConfig::BE_FAVORED;
    }

    public function isNoticedWhileReplied() {
        return $this->notice_config & NoticeConfig::BE_REPLIED;
    }

    public function isNoticedWhileFowarded() {
        return $this->notice_config & NoticeConfig::BE_FOWARDED;
    }

    public function isNoticedWhilePrivateMsg() {
        return $this->notice_config & NoticeConfig::PRIVATE_MSG;
    }

    public function initUser() {
        $now = time();
        $this->status = UserStatus::INIT;
        $this->create_time = $now;
        $this->last_login_time = $now;
        $this->last_modify_time = $now;
        $this->notice_config = $this->getAllNoticeConfig();
    }

    public function recoverUser(UserData $user) {
        $this->uid = $user->uid;
        $this->city = $user->city;
        $this->sex = $user->sex;
        $this->photo = $user->photo;
        $this->notice_config = $user->notice_config;
        $this->description = $user->description;
        $this->url = $user->url;
        $this->grade = $user->grade;
        $this->create_time = $user->create_time;
        $userData->setIsNewRecord(false);
        $res = $userData->save();
        return $res;
    }
    
    public function updateStatus($status)
    {
        $this->status = $status;
        $this->last_modify_time = time();
        $this->setIsNewRecord(false);
        $res = $this->update(array('status', 'last_modify_time '));
        if (false === $res) {
            throw new Exception('error in updating status for user[' . $this->email . '], uid[' . $this->uid . ']', ErrorDef::COMMON_ERROR_SYS);
        }
    }

    public function editDatas(UserData $userData)
    {
        $update_attributes = array();
        $update_data= array();
        foreach(self::$canEditFields as $key)
        {
            if (isset ($userData->$key) && $userData->$key != $this->$key)
            {
                $update_attributes[] = $key;
                $update_data[$key] = $userData->$key;
                $this->$key = $userData->$key;
            }
        }
        
        $this->last_modify_time = time();
        $update_attributes[] = 'last_modify_time';
        $this->setIsNewRecord(false);
        $res = $this->update($update_attributes);
        if (false === $res) {
            throw new Exception('error in updating data for user[' . $this->email . '], uid[' . $this->uid . '] and data [' . print_r($update_data, true) . ']' , ErrorDef::COMMON_ERROR_SYS);
        }
    }

    public function updateDatas($attributes) {
        $res = $this->update($attributes);
        if (false === $res) {
            throw new Exception('error in updating data for user[' . $this->email . '], uid[' . $this->uid . '] and attributes [' . print_r($attributes, true) . ']', ErrorDef::COMMON_ERROR_SYS);
        }
    }

    private function getAllNoticeConfig() {
        return NoticeConfig::BE_FAVORED |
        NoticeConfig::BE_FOLLOWED |
        NoticeConfig::BE_FOWARDED |
        NoticeConfig::BE_REPLIED |
        NoticeConfig::PRIVATE_MSG;
    }

    public static function encodePassword($pwd)
    {
        return md5($pwd);
    }
    
    const CITY_MASK = 0x00FF;
    
    static $canEditFields = array('uname', 'password', 'city', 'sex', 'photo', 'notice_config', 'description', 'grade', 'url');
}
